import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Like, In } from 'typeorm';
import { Tool } from './entities/tool.entity';
import { CreateToolDto } from './dto/create-tool.dto';
import { UpdateToolDto } from './dto/update-tool.dto';
import { QueryToolsDto } from './dto/query-tools.dto';

/**
 * 工具服务
 */
@Injectable()
export class ToolsService {
  constructor(
    @InjectRepository(Tool)
    private toolsRepository: Repository<Tool>,
  ) {}

  /**
   * 创建工具
   */
  async create(createToolDto: CreateToolDto): Promise<Tool> {
    const tool = this.toolsRepository.create(createToolDto);
    return await this.toolsRepository.save(tool);
  }

  /**
   * 查询工具列表
   */
  async findAll(query: QueryToolsDto) {
    const {
      page = 1,
      limit = 20,
      categoryId,
      tags,
      isFeatured,
      isSponsored,
      search,
      sortBy = 'createdAt',
      order = 'DESC',
    } = query;

    const queryBuilder = this.toolsRepository
      .createQueryBuilder('tool')
      .leftJoinAndSelect('tool.category', 'category')
      .leftJoinAndSelect('tool.tags', 'tags')
      .leftJoin('tool.reviews', 'reviews', 'reviews.status = :status', { status: 'approved' })
      .addSelect('COUNT(DISTINCT reviews.id)', 'tool_reviewCount')
      .groupBy('tool.id')
      .addGroupBy('category.id')
      .addGroupBy('tags.id');

    // 分类筛选
    if (categoryId) {
      queryBuilder.andWhere('tool.categoryId = :categoryId', { categoryId });
    }

    // 标签筛选
    if (tags && tags.length > 0) {
      queryBuilder.andWhere('tags.id IN (:...tags)', { tags });
    }

    // 特色工具
    if (isFeatured !== undefined) {
      queryBuilder.andWhere('tool.isFeatured = :isFeatured', { isFeatured });
    }

    // 推广工具
    if (isSponsored !== undefined) {
      queryBuilder.andWhere('tool.isSponsored = :isSponsored', { isSponsored });
    }

    // 搜索
    if (search) {
      queryBuilder.andWhere(
        '(tool.name LIKE :search OR tool.description LIKE :search)',
        { search: `%${search}%` },
      );
    }

    // 先获取总数
    const total = await queryBuilder.getCount();

    // 排序
    queryBuilder.orderBy(`tool.${sortBy}`, order);

    // 分页
    const skip = (page - 1) * limit;
    queryBuilder.skip(skip).take(limit);

    const result = await queryBuilder.getRawAndEntities();

    // 将 reviewCount 添加到实体中
    const toolsWithReviewCount = result.entities.map((tool, index) => ({
      ...tool,
      reviewCount: parseInt(result.raw[index].tool_reviewCount) || 0,
    }));

    return {
      data: toolsWithReviewCount,
      total,
      page: Number(page),
      limit: Number(limit),
      totalPages: Math.ceil(total / limit),
    };
  }

  /**
   * 查询单个工具
   */
  async findOne(id: number): Promise<any> {
    const queryBuilder = this.toolsRepository
      .createQueryBuilder('tool')
      .leftJoinAndSelect('tool.category', 'category')
      .leftJoinAndSelect('tool.tags', 'tags')
      .leftJoin('tool.reviews', 'reviews', 'reviews.status = :status', { status: 'approved' })
      .addSelect('COUNT(DISTINCT reviews.id)', 'tool_reviewCount')
      .where('tool.id = :id', { id })
      .groupBy('tool.id')
      .addGroupBy('category.id')
      .addGroupBy('tags.id');

    const result = await queryBuilder.getRawAndEntities();

    if (!result.entities.length) {
      throw new NotFoundException(`工具 #${id} 不存在`);
    }

    // 增加浏览量
    await this.incrementViews(id);

    return {
      ...result.entities[0],
      reviewCount: parseInt(result.raw[0].tool_reviewCount) || 0,
    };
  }

  /**
   * 通过 slug 查询
   */
  async findBySlug(slug: string): Promise<any> {
    const queryBuilder = this.toolsRepository
      .createQueryBuilder('tool')
      .leftJoinAndSelect('tool.category', 'category')
      .leftJoinAndSelect('tool.tags', 'tags')
      .leftJoin('tool.reviews', 'reviews', 'reviews.status = :status', { status: 'approved' })
      .addSelect('COUNT(DISTINCT reviews.id)', 'tool_reviewCount')
      .where('tool.slug = :slug', { slug })
      .groupBy('tool.id')
      .addGroupBy('category.id')
      .addGroupBy('tags.id');

    const result = await queryBuilder.getRawAndEntities();

    if (!result.entities.length) {
      throw new NotFoundException(`工具 ${slug} 不存在`);
    }

    // 增加浏览量
    await this.incrementViews(result.entities[0].id);

    return {
      ...result.entities[0],
      reviewCount: parseInt(result.raw[0].tool_reviewCount) || 0,
    };
  }

  /**
   * 更新工具
   */
  async update(id: number, updateToolDto: UpdateToolDto): Promise<Tool> {
    const tool = await this.findOne(id);
    Object.assign(tool, updateToolDto);
    return await this.toolsRepository.save(tool);
  }

  /**
   * 删除工具
   */
  async remove(id: number): Promise<void> {
    const tool = await this.findOne(id);
    await this.toolsRepository.remove(tool);
  }

  /**
   * 增加浏览量
   */
  async incrementViews(id: number): Promise<void> {
    await this.toolsRepository.increment({ id }, 'views', 1);
  }

  /**
   * 增加点赞数
   */
  async incrementUpvotes(id: number): Promise<void> {
    await this.toolsRepository.increment({ id }, 'upvotes', 1);
  }

  /**
   * 获取热门工具
   */
  async getPopular(limit = 10): Promise<any[]> {
    const queryBuilder = this.toolsRepository
      .createQueryBuilder('tool')
      .leftJoinAndSelect('tool.category', 'category')
      .leftJoinAndSelect('tool.tags', 'tags')
      .leftJoin('tool.reviews', 'reviews', 'reviews.status = :status', { status: 'approved' })
      .addSelect('COUNT(DISTINCT reviews.id)', 'tool_reviewCount')
      .groupBy('tool.id')
      .addGroupBy('category.id')
      .addGroupBy('tags.id')
      .orderBy('tool.views', 'DESC')
      .take(limit);

    const result = await queryBuilder.getRawAndEntities();
    
    return result.entities.map((tool, index) => ({
      ...tool,
      reviewCount: parseInt(result.raw[index].tool_reviewCount) || 0,
    }));
  }

  /**
   * 获取特色工具
   */
  async getFeatured(limit = 10): Promise<any[]> {
    const queryBuilder = this.toolsRepository
      .createQueryBuilder('tool')
      .leftJoinAndSelect('tool.category', 'category')
      .leftJoinAndSelect('tool.tags', 'tags')
      .leftJoin('tool.reviews', 'reviews', 'reviews.status = :status', { status: 'approved' })
      .addSelect('COUNT(DISTINCT reviews.id)', 'tool_reviewCount')
      .where('tool.isFeatured = :isFeatured', { isFeatured: true })
      .groupBy('tool.id')
      .addGroupBy('category.id')
      .addGroupBy('tags.id')
      .orderBy('tool.createdAt', 'DESC')
      .take(limit);

    const result = await queryBuilder.getRawAndEntities();
    
    return result.entities.map((tool, index) => ({
      ...tool,
      reviewCount: parseInt(result.raw[index].tool_reviewCount) || 0,
    }));
  }

  /**
   * 获取推广工具
   */
  async getSponsored(limit = 5): Promise<any[]> {
    const queryBuilder = this.toolsRepository
      .createQueryBuilder('tool')
      .leftJoinAndSelect('tool.category', 'category')
      .leftJoinAndSelect('tool.tags', 'tags')
      .leftJoin('tool.reviews', 'reviews', 'reviews.status = :status', { status: 'approved' })
      .addSelect('COUNT(DISTINCT reviews.id)', 'tool_reviewCount')
      .where('tool.isSponsored = :isSponsored', { isSponsored: true })
      .groupBy('tool.id')
      .addGroupBy('category.id')
      .addGroupBy('tags.id')
      .orderBy('tool.createdAt', 'DESC')
      .take(limit);

    const result = await queryBuilder.getRawAndEntities();
    
    return result.entities.map((tool, index) => ({
      ...tool,
      reviewCount: parseInt(result.raw[index].tool_reviewCount) || 0,
    }));
  }

  /**
   * 获取相关工具推荐
   * 基于同分类、同标签的工具进行推荐
   */
  async getRelatedTools(toolId: number, limit = 6): Promise<any[]> {
    const tool = await this.toolsRepository.findOne({
      where: { id: toolId },
      relations: ['category', 'tags'],
    });

    if (!tool) {
      return [];
    }

    const tagIds = tool.tags?.map(tag => tag.id) || [];
    
    const queryBuilder = this.toolsRepository
      .createQueryBuilder('tool')
      .leftJoinAndSelect('tool.category', 'category')
      .leftJoinAndSelect('tool.tags', 'tags')
      .leftJoin('tool.reviews', 'reviews', 'reviews.status = :status', { status: 'approved' })
      .addSelect('COUNT(DISTINCT reviews.id)', 'tool_reviewCount')
      .where('tool.id != :toolId', { toolId })
      .groupBy('tool.id')
      .addGroupBy('category.id')
      .addGroupBy('tags.id');

    // 优先推荐同分类或同标签的工具
    if (tool.categoryId || tagIds.length > 0) {
      queryBuilder.andWhere(
        '(tool.categoryId = :categoryId OR tags.id IN (:...tagIds))',
        { categoryId: tool.categoryId, tagIds: tagIds.length > 0 ? tagIds : [0] }
      );
    }

    // 按评分和浏览量排序
    queryBuilder
      .orderBy('tool.rating', 'DESC')
      .addOrderBy('tool.views', 'DESC')
      .take(limit);

    const result = await queryBuilder.getRawAndEntities();
    
    return result.entities.map((tool, index) => ({
      ...tool,
      reviewCount: parseInt(result.raw[index].tool_reviewCount) || 0,
    }));
  }
}







